import { BugOutlined } from "@ant-design/icons";
import IconFont from "@/assets/icon.js";

import {
  ExtensionCategory,
  Graph,
  HoverActivate,
  idOf,
  register,
  Tooltip,
} from "@antv/g6";
import { ReactNode } from "@antv/g6-extension-react";
import { Flex, Typography } from "antd";
import { useEffect, useRef } from "react";
import { createRoot } from "react-dom/client";

const { Text } = Typography;

const ACTIVE_COLOR = "#f6c523";
const COLOR_MAP = {
  "pre-inspection": "#3fc1c9",
  problem: "#8983f3",
  inspection: "#f48db4",
  solution: "#ffaa64",
};

class HoverElement extends HoverActivate {
  getActiveIds(event) {
    const { model, graph } = this.context;
    const { targetType, target } = event;
    const targetId = target.id;

    const ids = [targetId];
    if (targetType === "edge") {
      const edge = model.getEdgeDatum(targetId);
      ids.push(edge.source, edge.target);
    } else if (targetType === "node") {
      ids.push(...model.getRelatedEdgesData(targetId).map(idOf));
    }

    graph.frontElement(ids);

    return ids;
  }
}

register(ExtensionCategory.NODE, "react", ReactNode);
register(ExtensionCategory.BEHAVIOR, "hover-element", HoverElement);

const Node = ({ data }) => {
  const { text, type } = data.data;

  const isHovered = data.states?.includes("active");
  const isSelected = data.states?.includes("selected");
  const color = isHovered ? ACTIVE_COLOR : COLOR_MAP[type];

  const containerStyle = {
    width: "100%",
    height: "100%",
    background: color,
    border: `3px solid ${color}`,
    borderRadius: 16,
    cursor: "pointer",
  };

  if (isSelected) {
    Object.assign(containerStyle, { border: `3px solid #000` });
  }

  return (
    <Flex style={containerStyle} align="center" justify="center">
      <Flex
        vertical
        style={{ padding: "8px 16px", textAlign: "center" }}
        align="center"
        justify="center"
      >
        {type === "problem" && (
          // <BugOutlined
          //   style={{ color: "#fff", fontSize: 24, marginBottom: 8 }}
          // />
          <IconFont
            type="icon-tuoputu_fuwuqi"
            style={{ color: "#fff", fontSize: 50, marginBottom: 8 }}
          />
        )}
        <Text style={{ color: "#fff", fontWeight: 600, fontSize: 16 }}>
          {text}
        </Text>
      </Flex>
    </Flex>
  );
};

export const PerformanceDiagnosisFlowchart = () => {
  let graph = null;
  const containerRef = useRef();

  useEffect(() => {
    fetch("https://assets.antv.antgroup.com/g6/performance-diagnosis.json")
      .then((res) => res.json())
      .then((data) => {
        data.combos = [
          {
            id: "A",
            style: {
              type: "rect",
            },
          },
        ];
        data.nodes.push(
          {
            id: "18",
            data: {
              type: "solution",
              text: "Infrastructure problem - add cores",
            },
            combo: "A",
          },
          {
            id: "19",
            data: {
              type: "solution",
              text: "Infrastructure problem - add cores",
            },
            combo: "A",
          }
        );
        data.edges.push(
          {
            source: "15",
            target: "18",
            data: {
              text: "NO",
            },
          },
          {
            source: "15",
            target: "19",
            data: {
              text: "NO",
            },
          }
        );
        graph = new Graph({
          container: containerRef.current,
          data,
          animation: false,
          autoFit: "view",
          node: {
            type: "react",
            style: (d) => {
              const style = {
                component: <Node data={d} />,
                ports: [{ placement: "top" }, { placement: "bottom" }],
              };

              const size = {
                "pre-inspection": [240, 120],
                problem: [200, 120],
                inspection: [330, 100],
                solution: [200, 120],
              }[d.data.type] || [200, 80];

              Object.assign(style, {
                size,
                dx: -size[0] / 2,
                dy: -size[1] / 2,
              });
              return style;
            },
            state: {
              active: {
                halo: false,
              },
              selected: {
                halo: false,
              },
            },
          },
          edge: {
            type: "cubic-vertical",
            style: {
              lineWidth: 3,
              radius: 20,
              stroke: "#8b9baf",
              endArrow: true,
              labelText: (d) => d.data.text,
              labelFill: "#8b9baf",
              labelFontWeight: 600,
              labelBackground: true,
              labelBackgroundFill: "#f8f8f8",
              labelBackgroundOpacity: 1,
              labelBackgroundLineWidth: 3,
              labelBackgroundStroke: "#8b9baf",
              labelPadding: [1, 10],
              labelBackgroundRadius: 4,
              router: {
                type: "orth",
              },
            },
            state: {
              active: {
                stroke: ACTIVE_COLOR,
                labelBackgroundStroke: ACTIVE_COLOR,
                halo: false,
              },
            },
          },
          combo: {
            type: "rect",
            style: {
              radius: 8,
              labelText: (d) => d.id,
            },
          },
          layout: {
            type: "antv-dagre",
          },
          behaviors: [
            "zoom-canvas",
            "drag-canvas",
            "hover-element",
            "click-select",
          ],
          plugins: [
            {
              type: "tooltip",
              getContent: (e, items) => {
                let result = `<h4>Custom Content</h4>`;
                items.forEach((item) => {
                  result += `<p>Type: ${item.id}</p>`;
                });
                return result;
              },
            },
          ],
        });
        graph.render();
      });
    return () => {
      if (graph) {
        graph.destroy();
      }
    };
  }, []);

  return (
    <div style={{ width: "100%", height: "100%" }} ref={containerRef}></div>
  );
};

// const root = createRoot(document.getElementById('container'));
// root.render(<PerformanceDiagnosisFlowchart />);

export default PerformanceDiagnosisFlowchart;
